/*
 * Copyright (C) 2019 ~ 2022 Uniontech Software Technology Co.,Ltd.
 *
 * Author:     yanghongwei <yanghongwei@uniontech.com>
 *
 * Maintainer: yanghongwei <yanghongwei@uniontech.com>
 */

#ifndef FANOTIFY_H
#define FANOTIFY_H

#include "abstractnotify.h"

#include <atomic>
#include <list>

/**
 * @brief fanotify的具体实现
 */
// TODO: 目前多个process同时添加移除已做处理，但是需要大量测试验证是否存在问题
class FaNotify : public AbstractNotify
{
public:
    FaNotify();
    ~FaNotify() override;

    bool init() override; // fanotify的初始化
    bool addNode(const NotifyNode &node) override; // 添加一个要监听的节点
    bool removeNode(const NotifyNode &node) override; // 移除一个已经监听的节点
    bool start() override; // 启动监听线程
    bool stop() override; // 停止监听线程
    void run() override; // 线程执行体
    bool isRunning() override; // 线程是否在运行

private:
    uint32_t getFaNotifyEvents(const NotifyNode &node); // FileEvent转换为fanotify event
    uint32_t getFileNotifyEvents(const uint32_t &events); // fanotify event转换为FileEvent
    void handleEvent(struct fanotify_event_metadata *metadata, int len); // 事件处理

    bool addNode(const NotifyNode &node, bool isSave); // 添加一个要监听的节点

private:
    std::atomic<bool> m_running; // 线程运行状态
    int m_fd; // fanotify初始化句柄
    std::list<NotifyNode> m_notifyNodeList; // 保存监听的节点
};

#endif // FANOTIFY_H
